#include "gstreamer_2.h"


void play_01(int argc, char *argv[])
{
    GstElement *pipeline, *source, *sink;
    GstBus * bus;
    GstMessage * message;

    gst_init(&argc, &argv);

    source = gst_element_factory_make("videotestsrc", "source");
    sink = gst_element_factory_make("autovideosink", "sink");

    pipeline = gst_pipeline_new("test-pipeline");

    if(!pipeline || !source || !sink) {
        g_printerr("Not all elements could be created!");
        return;
    }

    gst_bin_add_many(GST_BIN(pipeline), source, sink, nullptr);
    if(!gst_element_link(source, sink)) {
        g_printerr("elements could not be linked");
        gst_object_unref(pipeline);
        return;
    }

    g_object_set(source, "pattern", 0, nullptr);

    int ret = gst_element_set_state(pipeline, GST_STATE_PLAYING);
    if(ret == GST_STATE_CHANGE_FAILURE) {
        g_printerr("Unable to set the pipeline to the playing state");
        gst_object_unref(pipeline);
        return;
    }

    bus = gst_element_get_bus(pipeline);
    message = gst_bus_timed_pop_filtered(bus, GST_CLOCK_TIME_NONE, (GstMessageType)(GST_MESSAGE_ERROR | GST_MESSAGE_EOS));

    if(message != nullptr) {
        GError *err;
        gchar *debug_info;

        switch (GST_MESSAGE_TYPE(message)) {
            case GST_MESSAGE_ERROR:
                gst_message_parse_error(message, &err, &debug_info);
                g_printerr("Error received from element %s:%s\n", GST_OBJECT_NAME(message->src), err->message);
                g_printerr("Debugging infomation: %s\n", debug_info ? debug_info : "none");
                g_clear_error(&err);
                g_free(debug_info);
                break;
            case GST_MESSAGE_EOS:
                g_print("End of stream reached.\n");
                break;
            default:
                g_printerr("Unexpected message received.\n");
                break;
        }
        gst_message_unref(message);
    }

    gst_object_unref(bus);
    gst_element_set_state(pipeline, GST_STATE_NULL);
    gst_object_unref(pipeline);
}
